home *** CD-ROM | disk | FTP | other *** search
- /*
- * xfm.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * XF(ast)M(oments)
- *
- * calculate moments, M, of a gray scale image up to m33,
- * based on a filter array, Y, extracted from the imput image,
- * and a mask CM:
- *
- * M = CM*Y*CM'; CM': transposed CM, *: matrix mult.
- *
- * ref: M. Hatamian,
- * IEEE Trans. on Acoust., Speech and Signal Proc.,
- * ASSP-34, 546 - 553, 1986;
- * Proc of Digital Signal Proc. - 87,
- * V. Cappellini & A. G. Constantinides, Eds.
- * Elsevier Sci. Publ. B. V. (North Holland), 1987
- *
- * version based on M. Hatamian's code implementing recursion
- * to obtain Y-matrix;
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include "xfm.h"
-
- #define ON 1
- #define OFF 0
-
- #define RESET ON /* reset graphics screen */
- #define NO_RESET OFF
-
-
- #undef DEBUG
-
-
- extern char *optarg;
- extern int optind, opterr;
- extern short tiffInput; /* flag=0 if no ImageIn to set tags; else =1 */
-
-
- int FILTER_TEST = OFF;
- int WRITE_FILE = OFF;
-
-
-
- void
- fail_alloc (str, code)
- char *str;
- int code;
- {
- printf ("\n...memory alloc for %s failed\n", str);
- exit (code);
- }
-
-
- /*
- * usage of routine
- */
- void
- usage (char *progname)
- {
- progname = last_bs (progname);
- printf ("USAGE: %s inimg [-d] [-w file] [-t] [-L]\n", progname);
- printf ("\n%s iteratively evaluates moments of a convex shape up to 3rd order,\n\n", progname);
- printf ("ARGUMENTS:\n");
- printf (" inimg: input image filename (TIF)\n\n");
- printf ("OPTIONS:\n");
- printf (" -d: default mode: evaluate moments of binary region\n");
- printf (" -w: write file (.mdt) to disk\n");
- printf (" -t: generate test filter array\n");
- printf (" -L: print Software License for this module\n");
-
- exit (1);
- }
-
- void
- main (argc, argv)
- int argc;
- char *argv[];
- {
- int i, j;
- int nr, nc;
-
- int jmin, imin, jmax, imax;
- int left_x, right_x;
-
- float m00;
- float mu00, mu11, mu02, mu20;
- float xc, yc, rg, dent;
-
- int xdim, ydim;
- float *y[MDIM], *m[MDIM];
-
- char *buf;
- int i_arg;
- FILE *file;
- Image *imgIn; /* input image */
-
-
- /*
- * cmd line options
- */
- static char *optstring = "dtw:L";
-
-
- /*
- * parse command line
- */
- optind = 2;
- opterr = ON; /* give error messages */
-
- if (argc < 2)
- usage (argv[0]);
-
- while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
- switch (i_arg) {
- case 'd':
- printf ("...option %c: default mode\n", i_arg);
- FILTER_TEST = OFF;
- break;
- case 't':
- printf ("...option %c: generate test filter array\n", i_arg);
- FILTER_TEST = ON;
- break;
- case 'w':
- printf ("...option %c: write file %s to disk\n",
- i_arg, buf = optarg);
-
- if ((file = fopen (buf, "w")) == NULL) {
- puts ("\n...could not open output file");
- exit (1);
- }
- WRITE_FILE = ON;
- break;
- case 'L':
- print_sos_lic ();
- exit (0);
- default:
- printf ("...unknown command line argument encountered\n");
- usage (argv[0]);
- exit (1);
- break;
- }
- }
-
- /*
- * get the input image
- */
- imgIn = ImageIn (argv[1]);
- if (imgIn->bps == 8 && imgIn->spp == 3) {
- printf ("Got RGB image!!!\n");
- fprintf (stderr, "Can only work with Grayscale or Binary TIFF files!!!\n");
- exit (1);
- }
- if (imgIn->bps != 1) {
- printf ("Got Grayscale image!!!\n");
- fprintf (stderr, "Can only work with Binary TIFF files!!!\n");
- exit (1);
- }
-
- /* reset tiffInput so that we write a grayscale file (i.e tags are not copied) */
- tiffInput = 0;
-
- jmin = imin = 0;
- jmax = imgIn->width;
- imax = imgIn->height;
-
- left_x = jmin;
- right_x = jmax - 1;
- nc = jmax - jmin;
- nr = imax - imin;
-
- #ifdef DEBUG
- printf ("\n...nc = %d, nr = %d\n", nc, nr);
- #endif
-
-
- /*
- * zero outer border of image
- */
- zero_border (imgIn, 2);
-
-
- /*
- * memory allocation for filter and moment arrays
- */
- xdim = ydim = MDIM;
- for (j = 0; j < ydim; j++) {
- if ((y[j] = (float *) calloc (xdim, sizeof (float))) == NULL)
- fail_alloc ("y", 1);
- }
- for (j = 0; j < ydim; j++) {
- if ((m[j] = (float *) calloc (xdim, sizeof (float))) == NULL)
- fail_alloc ("m", 1);
- }
-
- /*
- * begin moment evaluation
- */
- if (FILTER_TEST == ON) { /* test filter array */
- printf ("...initialize a test filter array\n\n");
- for (j = 0; j < ydim; j++) {
- for (i = 0; i < xdim; i++) {
- if ((j == 0) || (i == 0))
- *(y[j] + i) = (float) 1.0;
- if ((j == 1) && (i == 1))
- *(y[j] + i) = (float) 1.0;
- if ((j == 1) && (i == 2))
- *(y[j] + i) = (float) 1.0;
- if ((j == 2) && (i == 1))
- *(y[j] + i) = (float) 1.0;
- if ((j == 2) && (i == 2))
- *(y[j] + i) = (float) 1.0;
-
- printf (" %2.0f ", *(y[j] + i));
- if ((i + 1) % 4 == 0)
- printf ("\n");
- }
- printf ("\n");
- }
- }
- else /* compute filter output from given image */
- filter_recursion (left_x, right_x, nr, nc, y, xdim, ydim, imgIn);
-
-
- /*
- * evaluate moments by matrix multiplication
- */
- printf ("\n...matrix multiplication to obtain moments\n");
-
- eval_mom (y, m, MDIM);
-
-
- /*
- * compute centroid and central moments
- */
- central_moments (m, &mu00, &mu11, &mu02, &mu20, &xc, &yc, &rg, &dent);
-
-
- /*
- * print area-normalized and central moments
- */
- printf ("\n...moments:\n");
- m00 = *(m[0] + 0);
- for (i = 0; i < (int) MDIM; i++) {
- for (j = 0; j < (int) MDIM; j++) {
- *(m[i] + j) /= m00;
- printf (" m[%d][%d]/m00 = %f\n", i, j, *(m[i] + j));
- }
- }
- printf (" %f\n", m00);
- printf ("\n...central moments:\n");
- printf ("...mu00 = %f, mu11 = %f\n", mu00, mu11);
- printf ("...mu02 = %f, mu20 = %f\n", mu02, mu20);
- printf ("...rg = %f\n", rg);
- printf ("...dent = %f\n", dent);
-
-
- /*
- * write data file of format ( .mdt)
- */
- if (WRITE_FILE == ON) {
- write_mdt_file (file, m, (int) MDIM, m00, mu00,
- mu11, mu02, mu20, xc, yc, rg, dent);
- fclose (file);
- }
-
- for (j = 0; j < ydim; j++) {
- free (y[j]);
- free (m[j]);
- }
- }
-